package com.ciaojian.client.policy.impl.coupon;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ciaojian.core.mapper.MyCouponMapper;
import com.ciaojian.core.model.HaircutService;
import com.ciaojian.core.model.Order;
import com.ciaojian.core.model.vo.CouponVo;
import com.ciaojian.core.service.ICouponDiscount;
import com.ciaojian.core.util.BigDecimalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 优惠券优惠
 *
 * @author Atlakyn
 */
@Slf4j
@Service
public class CodeDiscount implements ICouponDiscount<Map<String, Object>> {
    @Resource
    private MyCouponMapper myCouponMapper;

    /**
     * 计算优惠券优惠后的价格
     *
     * @param couponInfo 优惠信息 {code:券码,userId:用户 id}
     * @param amount     原价格
     * @return 计算后的价格
     */
    @Override
    public BigDecimal discountAmount(Map<String, Object> couponInfo, BigDecimal amount) {
        // 原价
        BigDecimal originalAmount = amount;
        // 取出优惠券码
        List codes = MapUtil.get(couponInfo, "code", List.class);
        Order order = MapUtil.get(couponInfo, "order", Order.class);

        for (Object code : codes) {
            CouponVo couponVo = myCouponMapper.getCouponByCode(code.toString());
            if (condition(order, couponVo)) {
                switch (couponVo.getCouponType()) {
                    // 如果是直减券,可以叠加; 直接是 原价 - 优惠金额
                    case 0:
                        amount = amount.subtract(couponVo.getReduction());
                        break;
                    // 折扣券
                    case 1:
                        BigDecimal reduce = BigDecimalUtil.reduce(couponVo.getDiscount(), BigDecimalUtil.TEN);
                        amount = amount.multiply(reduce);
                        break;
                    default:
                }
            }
        }
        return amount.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : amount;
    }


    /**
     * 使用条件
     * <p>多条件组装</p>
     *
     * @return 满足全部条件返回 true
     */
    private boolean condition(Order order, CouponVo couponVo) {
        return checkNull(couponVo) && belongUser(order, couponVo) && checkFull(order, couponVo) && containService(couponVo, order);
    }

    /**
     * 是否用券
     *
     * @param couponVo 优惠券 Vo
     * @return 不为空返回 true
     */
    private boolean checkNull(CouponVo couponVo) {
        return couponVo != null;
    }

    /**
     * 券是否可用于当前服务
     *
     * @param couponVo 优惠券
     * @param order    订单
     * @return 可用返回 true
     */
    private boolean containService(CouponVo couponVo, Order order) {
        LambdaQueryWrapper<HaircutService> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HaircutService::getTitle, order.getType());
        HaircutService haircutService = new HaircutService().selectOne(queryWrapper);
        String serviceList = couponVo.getServiceList();
        if (StrUtil.isBlank(serviceList)) {
            return true;
        } else {
            String[] split = serviceList.split(",");
            for (String s : split) {
                // 如果其中一个包含了这项服务则返回 true
                if (s.equals(String.valueOf(haircutService.getId()))) {
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * 检查券是否属于用户
     *
     * @return 属于返回 true
     */
    private Boolean belongUser(Order order, CouponVo couponVo) {
        return order.getUserId().compareTo(couponVo.getUserId()) == 0;
    }

    /**
     * 用券门槛
     *
     * @param order    订单
     * @param couponVo 优惠券 Vo
     * @return 达到用券门槛返回 true
     */
    private boolean checkFull(Order order, CouponVo couponVo) {
        return order.getGoodsTotal().compareTo(couponVo.getFull()) >= 0;
    }
}
